package net.forty2ware.vintagesofa

import org.apache.commons.lang.builder.EqualsBuilder
import org.apache.commons.lang.builder.HashCodeBuilder

// http://wiki.apache.org/couchdb/HTTP_database_API
class Database {

  static validNameRegex = ~/^[a-z0-9_$()+-\/]+$/

  private CouchDbHelper couchDbHelper = new CouchDbHelper()
  Server server
  String name
  def info = [:]

  void setName(String name) {
    if (!(name ==~ validNameRegex)) {
      throw new RuntimeException('Invalid database name. A database must be named with all lowercase characters (a-z), digits (0-9), or any of the _$()+-/ characters.')
    }
    this.name = name
  }

  def create() {
    return couchDbHelper.put(this, '')
  }

  def delete() {
    return couchDbHelper.delete(this, '')
  }

  def refresh() {
    def response = couchDbHelper.get(this, '')
    info = response ?: info
    return response
  }

  Document getDocument(name = null, revision = null) {
    // is this the new paradigm?
    if (name instanceof Map) {
      def map = name
      name = map.name
      revision = map.revision
    }
    return new Document(
      'database'    : this,
      'name'        : name,
      'revision'    : revision,
    )
  }

  DesignDocument getDesignDocument(name, revision, language) {
    // is this the new paradigm?
    if (name instanceof Map) {
      def map = name
      name = map.name
      revision = map.revision
      language = map.language
    }

    name = (name ==~ /^_design\/.*$/) ? name :  "_design/${name}"

    return new DesignDocument(
      'database'    : this,
      'name'        : name,
      'revision'    : revision,
      'language'    : language,
    )
  }

  // http://wiki.apache.org/couchdb/Compaction
  def compact() {
    return true
  }

  @Override
  public boolean equals(Object o) {
    if (o == null) { return false; }
    if (o == this) { return true; }
    if (obj.getClass() != getClass()) {
      return false;
    }

    Database rhs = (Database)o;
    return new EqualsBuilder()
      .append(server, rhs.server)
      .append(name, rhs.name)
      .isEquals()
  } 

  @Override
  public int hashCode() {
    return new HashCodeBuilder(13, 75)
      .append(server)
      .append(name)
      .toHashCode()
  }

}
